home *** CD-ROM | disk | FTP | other *** search
/ Sprite 1984 - 1993 / Sprite 1984 - 1993.iso / src / X11R4 / cmds / X / ddx / dec / qdss / qdcopy.c < prev    next >
Encoding:
C/C++ Source or Header  |  1989-11-26  |  9.6 KB  |  285 lines

  1. /***********************************************************
  2. Copyright 1987, 1988 by Digital Equipment Corporation, Maynard, Massachusetts,
  3. and the Massachusetts Institute of Technology, Cambridge, Massachusetts.
  4.  
  5.                         All Rights Reserved
  6.  
  7. Permission to use, copy, modify, and distribute this software and its 
  8. documentation for any purpose and without fee is hereby granted, 
  9. provided that the above copyright notice appear in all copies and that
  10. both that copyright notice and this permission notice appear in 
  11. supporting documentation, and that the names of Digital or MIT not be
  12. used in advertising or publicity pertaining to distribution of the
  13. software without specific, written prior permission.  
  14.  
  15. DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
  16. ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
  17. DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
  18. ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
  19. WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
  20. ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
  21. SOFTWARE.
  22.  
  23. ******************************************************************/
  24.  
  25. #include "X.h"
  26. #include "windowstr.h"
  27. #include "gcstruct.h"
  28. #include "mi.h"
  29.  
  30. #include "qd.h"
  31. #include "qdgc.h"
  32.  
  33. /* due to validation...                            *
  34.  *    if this is called, pDstDrawable is SURELY a DRAWABLE_WINDOW.    *
  35.  *    -unless, of course, it's a fake window, called from qdCopyArea
  36.  */
  37. RegionPtr
  38. qdCopyAreaWin(pSrcDrawable, pDstDrawable,
  39.           pGC, srcx, srcy, width, height, dstx, dsty)
  40.     register DrawablePtr pSrcDrawable;
  41.     register DrawablePtr pDstDrawable;
  42.     GCPtr    pGC;   /* composite clip region here is that of pDstDrawable */
  43.     int        srcx, srcy;
  44.     int        width, height;
  45.     int        dstx, dsty;
  46. {
  47.     if ((width == 0) || (height == 0)) return NULL;
  48.  
  49.     if (pSrcDrawable->type == DRAWABLE_WINDOW) {
  50.     WindowPtr    psrcwin;
  51.     int        abssrcx, abssrcy;    /* screen coordinates */
  52.     int     absdstx, absdsty;    /* screen coordinates */
  53.  
  54.     RegionRec    pcompclip[1];
  55.     psrcwin = (WindowPtr)pSrcDrawable;
  56.     abssrcx = QDWIN_X(psrcwin) + srcx;
  57.     abssrcy = QDWIN_Y(psrcwin) + srcy;
  58.     absdstx = pGC->lastWinOrg.x + dstx;
  59.     absdsty = pGC->lastWinOrg.y + dsty;
  60.  
  61.     /* set up pcompclip to be argument Box */
  62.     pcompclip->extents.x1 = abssrcx;
  63.     pcompclip->extents.x2 = abssrcx + width;
  64.     pcompclip->extents.y1 = abssrcy;
  65.     pcompclip->extents.y2 = abssrcy + height;
  66. #ifdef X11R4
  67.     pcompclip->data = NULL;
  68. #else
  69.     pcompclip->size = 1;
  70.     pcompclip->numRects = 1;
  71.     pcompclip->rects = (BoxPtr) Xalloc(sizeof(BoxRec));
  72.     pcompclip->rects[0] = pcompclip->extents;
  73. #endif
  74.  
  75.     if ( pGC->subWindowMode == IncludeInferiors) /* used by qdCopyWindow */
  76.         miIntersect( pcompclip, pcompclip, QDWIN_WINSIZE(psrcwin));
  77.     else
  78.         miIntersect( pcompclip, pcompclip, QDWIN_CLIPLIST(psrcwin));
  79.     miTranslateRegion(pcompclip, absdstx-abssrcx, absdsty-abssrcy);
  80.  
  81.     miIntersect( pcompclip, pcompclip, QDGC_COMPOSITE_CLIP(pGC));
  82.     tlbltregion(pGC, pcompclip, absdstx-abssrcx, absdsty-abssrcy);
  83. #ifdef X11R4
  84.     if (pcompclip->data && pcompclip->data->size) Xfree(pcompclip->data);
  85. #else
  86.     Xfree(pcompclip->rects);
  87. #endif
  88.     /*
  89.      * miHandleExposures wants window-relative coordinates
  90.      */
  91.     return miHandleExposures(pSrcDrawable, pDstDrawable, pGC,
  92.                  srcx, srcy, width, height, dstx, dsty, 0);
  93.     }
  94.     else if (pSrcDrawable->type == DRAWABLE_PIXMAP)
  95.     {
  96.     return (RegionPtr) tlspaca(pSrcDrawable, pDstDrawable,
  97.                 pGC, srcx, srcy, width, height, dstx, dsty);
  98.         
  99.     } else /* pSrcDrawable->type must be UNDRAWABLE_WINDOW */
  100.     return miCopyArea( pSrcDrawable, pDstDrawable,
  101.                 pGC, srcx, srcy, width, height, dstx, dsty);
  102. }
  103.  
  104. RegionPtr
  105. qdCopyArea( pSrcDrawable, pDstDrawable,
  106.                     pGC, srcx, srcy, width, height, dstx, dsty)
  107.     register DrawablePtr pSrcDrawable;
  108.     register DrawablePtr pDstDrawable;
  109.     GCPtr    pGC;   /* composite clip region here is that of pDstDrawable */
  110.     int        srcx, srcy;
  111.     int        width, height;
  112.     int        dstx, dsty;
  113. {
  114. /* We start with some magic to guard against both src and dst being
  115.  * pixmaps that fight for offscreen space.
  116.  */
  117.     if (pDstDrawable->type == DRAWABLE_PIXMAP) {
  118.     tlConfirmPixmap((QDPixPtr)pDstDrawable);
  119.     if (pSrcDrawable->type == DRAWABLE_PIXMAP)
  120.         tlConfirmPixmap((QDPixPtr)pSrcDrawable);
  121.     tlSinglePixmap((QDPixPtr)pDstDrawable);
  122.     }
  123.     if (pDstDrawable->type == DRAWABLE_PIXMAP
  124.     /* make sure dst is still off-screen */
  125.     && ((QDPixPtr)pDstDrawable)->planes
  126.     /* if src is Bitmap which is not offscreen, use mi */
  127.     && (pSrcDrawable->depth > 1 || ((QDPixPtr)pSrcDrawable)->planes)) {
  128.     RegionPtr region;
  129.  
  130.     SETUP_PIXMAP_AS_WINDOW(pDstDrawable, pGC);
  131.     CHECK_MOVED(pGC, pDstDrawable);
  132.     /*
  133.      * If src is Bitmap in plane different from dst, must use
  134.      * tlPlaneCopy. Otherwise, make fake window. (If src and
  135.      * dst are Bitmaps in the same plane, prefer qdCopyAreaWin, because
  136.      * it ultimately call tlbitblt, which correctly deals with
  137.      * overlapping src and dst.)
  138.      */
  139.     if (pSrcDrawable->depth == 1
  140.         && !(((QDPixPtr)pSrcDrawable)->planes
  141.            & ((QDPixPtr)pDstDrawable)->planes)) {
  142.         pGC->fgPixel = Allplanes;
  143.         pGC->bgPixel = 0;
  144.         tlPlaneBlt(pGC,
  145.                dstx + QDPIX_X((QDPixPtr)pDstDrawable),
  146.                dsty + QDPIX_Y((QDPixPtr)pDstDrawable),
  147.                width, height,
  148.                srcx + QDPIX_X((QDPixPtr)pSrcDrawable),
  149.                srcy + QDPIX_Y((QDPixPtr)pSrcDrawable),
  150.                ((QDPixPtr)pSrcDrawable)->planes);
  151.         region = NULL;
  152.     }
  153.         else
  154.         region = qdCopyAreaWin(pSrcDrawable, pDstDrawable,
  155.                    pGC, srcx, srcy, width, height, dstx, dsty);
  156.     CLEANUP_PIXMAP_AS_WINDOW(pGC);
  157.     return region;    
  158.     } else
  159.     return miCopyArea(pSrcDrawable, pDstDrawable,
  160.               pGC, srcx, srcy, width, height, dstx, dsty);
  161. }
  162.  
  163. /* Validation ensures that pDstDrawable is DRAWABLE_WINDOW. */
  164.  
  165. RegionPtr
  166. qdCopyPlane(pSrcDrawable, pDstDrawable,
  167.         pGC, srcx, srcy, width, height, dstx, dsty, bitPlane)
  168.     DrawablePtr     pSrcDrawable;
  169.     DrawablePtr        pDstDrawable;
  170.     GCPtr        pGC;
  171.     int         srcx, srcy;
  172.     int         width, height;
  173.     int         dstx, dsty;
  174.     unsigned long    bitPlane;
  175. {
  176.     int xOrg = dstx + pGC->lastWinOrg.x;
  177.     int yOrg = dsty + pGC->lastWinOrg.y;
  178.     unsigned long mask = 
  179.     pSrcDrawable->depth == 1 ? ((QDPixPtr)pSrcDrawable)->planes
  180.         : bitPlane;
  181.     if (pSrcDrawable->type == DRAWABLE_PIXMAP) {
  182.     int w = QDPIX_WIDTH((PixmapPtr)pSrcDrawable) - srcx;
  183.     int h = QDPIX_HEIGHT((PixmapPtr)pSrcDrawable) - srcy;
  184.     if (w > width) w = width;
  185.     if (h > height) h = height;
  186.     if (QDPIX_Y((QDPixPtr)pSrcDrawable) != NOTOFFSCREEN)
  187.         tlPlaneBlt(pGC, xOrg, yOrg, w, h,
  188.                srcx + QDPIX_X((QDPixPtr)pSrcDrawable),
  189.                srcy + QDPIX_Y((QDPixPtr)pSrcDrawable),
  190.                mask);
  191.     else {
  192.         RegionPtr pcl = QDGC_COMPOSITE_CLIP(pGC);
  193.         register BoxPtr    rects = REGION_RECTS(pcl);
  194.         int saveMask = ((QDPixPtr)pSrcDrawable)->planes;
  195.         int ic;
  196.         ((QDPixPtr)pSrcDrawable)->planes = mask;
  197.         for (ic = REGION_NUM_RECTS(pcl); --ic >= 0; rects++) {
  198.         BoxRec    cb;
  199.         cb.x1 = max( rects->x1, xOrg);
  200.         cb.y1 = max( rects->y1, yOrg);
  201.         cb.x2 = min( rects->x2, xOrg+width);
  202.         cb.y2 = min( rects->y2, yOrg+height);
  203.         if (cb.x1 < cb.x2 && cb.y1 < cb.y2)
  204.             tlBitmapBichrome(pGC, pSrcDrawable,
  205.                      pGC->fgPixel, pGC->bgPixel,
  206.                      xOrg - srcx, yOrg - srcy, &cb);
  207.         }
  208.         ((QDPixPtr)pSrcDrawable)->planes = saveMask;
  209.     }
  210.     }
  211.     else if (pSrcDrawable->type == DRAWABLE_WINDOW) {
  212.     WindowPtr    psrcwin;
  213.     int        abssrcx, abssrcy;    /* screen coordinates */
  214.     int     absdstx, absdsty;    /* screen coordinates */
  215.     
  216.     RegionRec    pcompclip[1];
  217.     RegionPtr    pSaveClip = QDGC_COMPOSITE_CLIP(pGC);
  218.     psrcwin = (WindowPtr)pSrcDrawable;
  219.     abssrcx = QDWIN_X(psrcwin) + srcx;
  220.     abssrcy = QDWIN_Y(psrcwin) + srcy;
  221.     absdstx = pGC->lastWinOrg.x + dstx;
  222.     absdsty = pGC->lastWinOrg.y + dsty;
  223.  
  224.     /* set up pcompclip to be argument Box */
  225.     pcompclip->extents.x1 = abssrcx;
  226.     pcompclip->extents.x2 = abssrcx + width;
  227.     pcompclip->extents.y1 = abssrcy;
  228.     pcompclip->extents.y2 = abssrcy + height;
  229. #ifdef X11R4
  230.     pcompclip->data = NULL;
  231. #else
  232.     pcompclip->size = 1;
  233.     pcompclip->numRects = 1;
  234.     pcompclip->rects = (BoxPtr) Xalloc(sizeof(BoxRec));
  235.     pcompclip->rects[0] = pcompclip->extents;
  236. #endif
  237.  
  238.     if ( pGC->subWindowMode == IncludeInferiors) /* used by qdCopyWindow */
  239.         miIntersect( pcompclip, pcompclip, QDWIN_WINSIZE(psrcwin));
  240.     else
  241.         miIntersect( pcompclip, pcompclip, QDWIN_CLIPLIST(psrcwin));
  242.     miTranslateRegion(pcompclip, absdstx-abssrcx, absdsty-abssrcy);
  243.     miIntersect( pcompclip, pcompclip, QDGC_COMPOSITE_CLIP(pGC));
  244.     QDGC_COMPOSITE_CLIP(pGC) = pcompclip;
  245.     tlPlaneBlt(pGC, xOrg, yOrg, width, height,
  246.            srcx + QDWIN_X((WindowPtr)pSrcDrawable),
  247.            srcy + QDWIN_Y((WindowPtr)pSrcDrawable),
  248.            mask);
  249.     QDGC_COMPOSITE_CLIP(pGC) = pSaveClip;
  250. #ifdef X11R4
  251.     if (pcompclip->data && pcompclip->data->size) Xfree(pcompclip->data);
  252. #else
  253.     Xfree(pcompclip->rects);
  254. #endif
  255.     }
  256.     return miHandleExposures(pSrcDrawable, pDstDrawable, pGC, srcx, srcy,
  257.                  width, height, dstx, dsty, bitPlane);
  258. }
  259.  
  260. RegionPtr
  261. qdCopyPlanePix(pSrcDrawable, pDstDrawable,
  262.         pGC, srcx, srcy, width, height, dstx, dsty, bitPlane)
  263.     DrawablePtr     pSrcDrawable;
  264.     DrawablePtr        pDstDrawable;
  265.     GCPtr        pGC;
  266.     int         srcx, srcy;
  267.     int         width, height;
  268.     int         dstx, dsty;
  269.     unsigned long    bitPlane;
  270. {
  271.     CHECK_MOVED(pGC, pDstDrawable);
  272.     if (QD_PIX_DATA((PixmapPtr)pDstDrawable) == NULL) {
  273.     RegionPtr region;
  274.     /* make dummy window and use that as the drawable */
  275.     SETUP_PIXMAP_AS_WINDOW(pDstDrawable, pGC);
  276.     region = qdCopyPlane(pSrcDrawable, pDstDrawable,
  277.         pGC, srcx, srcy, width, height, dstx, dsty, bitPlane);
  278.     CLEANUP_PIXMAP_AS_WINDOW(pGC);
  279.     return region;
  280.     }
  281.     else
  282.     return miCopyPlane(pSrcDrawable, pDstDrawable,
  283.                pGC, srcx, srcy, width, height, dstx, dsty, bitPlane);
  284. }
  285.